package emulator.hardware;

import java.io.PrintStream;
import java.util.Observer;

import emulator.EmulatorException;

/** General CPU interface */
public interface CPU {
	/** reset chip 
	 * @throws EmulatorException */
	void reset() throws EmulatorException;
	/** interrupt 
	 * @throws EmulatorException */
	void irq() throws EmulatorException;
	/** non-mask-able interrupt 
	 * @throws EmulatorException */
	void nmi() throws EmulatorException;
	
	/** single step (run for one command then stop) 
	 * @throws EmulatorException */
	void step() throws EmulatorException;
	/** single step (run for one command or subroutine then stop) 
	 * @throws EmulatorException */
	void stepOver() throws EmulatorException;
	/** run freely 
	 * @throws EmulatorException */
	void go() throws EmulatorException;
	/** stop execution */
	void halt();
	/** wait for stopped execution */
	void waitForHalt();
	/** add observer for running state (boolean) */
	void addRunningStateObserver(Observer observer);
	
	/** Print state to stdout 
	 * @throws EmulatorException */
	void printState(PrintStream out) throws EmulatorException;
	
	/** Set event handler for CPU events */
	void setEventHandler(CPUEventHandler handler);
	
	/** Set/clear simple breakpoint */
	void breakAt(HwNumber address, boolean enable);
	/** Set simple stop (break once) */
	void stopOnceAt(HwNumber address);
	/** Clear all stops (on time breaks & break on return) */
	void clearAllStops();
	/** Enable break on return (step out) */
	void enableBreakOnReturn(boolean enable);
	
	/** set register value */
	void setValue(String name, int value);
	/** get PC */
	int getPC();

}
